<?php
//header("Content-type: text/html; charset=gbk");
include_once "HttpUtil.php";
include_once "Constant.php";
include_once "connect.php";
include_once "weixinUtil.php";
//Needed model file
include_once $_SERVER['DOCUMENT_ROOT']."/model/User.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/Undertake.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/Task.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/Template.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/Stage.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/Location.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/Output.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/PictureOutput.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/TextOutput.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/EnumOutput.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/NumericalOutput.php";
//Needed dao file
include_once $_SERVER['DOCUMENT_ROOT']."/dao/UserDAO.php";
include_once $_SERVER['DOCUMENT_ROOT']."/dao/UndertakeDAO.php";
include_once $_SERVER['DOCUMENT_ROOT']."/dao/TaskDAO.php";
include_once $_SERVER['DOCUMENT_ROOT']."/dao/TemplateDAO.php";
include_once $_SERVER['DOCUMENT_ROOT']."/dao/StageDAO.php";
include_once $_SERVER['DOCUMENT_ROOT']."/dao/LocationDAO.php";
include_once $_SERVER['DOCUMENT_ROOT']."/dao/PictureOutputDAO.php";
include_once $_SERVER['DOCUMENT_ROOT']."/dao/TextOutputDAO.php";
include_once $_SERVER['DOCUMENT_ROOT']."/dao/EnumOutputDAO.php";
include_once $_SERVER['DOCUMENT_ROOT']."/dao/NumericalOutputDAO.php";

/**
 * Created by PhpStorm.
 * User: lwh
 * Date: 2017/8/1
 * Time: 9:28
 */

const PICTURE_OUTPUT = 0, TEXT_OUTPUT = 1, NUMERICAL_OUTPUT = 2, ENUM_OUTPUT = 3;
const OUTPUT_WITH_VALUE = 1;
//接收post数据，并强制转换为关联数组
$data = $_POST['data'];
$para = json_decode($data,true);
$result = completeTask($para);
echo $result;

function completeTask($para){
    //输入参数
    $userId = $para["userid"];
    $stageId = $para["stageid"];
    $finishTime = $para["finishtime"];
    $longitude = $para["longitude"];
    $latitude = $para["latitude"];
    $outputs = $para["outputs"];

//    var_dump($outputs);echo "<br /><br />";
    //更新相关信息
    $result = updateRelatedInfo($userId,$stageId,$finishTime,$longitude,$latitude);
    //插入输出
    $pictureoutput = null;
    $textoutputs = array();
    $numericaloutputs = array();
    $enumoutputs = array();
    //根据类型构建输出
    foreach($outputs as $output){
        $type = $output["type"];
        switch ($type){
            case PICTURE_OUTPUT:
                $pictureoutput = array();
                $pictureoutput["actionId"] = $output["actionId"];
                $pictureoutput["outputDesc"] = $output["desc"];
                $pictureoutput["outputValue"] = $output["value"];
                $pictureoutput["workerId"] = $userId;
                $pictureoutput["outputIndicator"] = OUTPUT_WITH_VALUE;
                break;
            case TEXT_OUTPUT:
                $textoutput = array();
                $textoutput["actionId"] = $output["actionId"];
                $textoutput["outputDesc"] = $output["desc"];
                $textoutput["outputValue"] = $output["value"];
                $textoutput["workerId"] = $userId;
                $textoutput["outputIndicator"] = OUTPUT_WITH_VALUE;
                array_push($textoutputs,$textoutput);
                break;
            case NUMERICAL_OUTPUT:
                $number = array();
                $number["actionId"] = $output["actionId"];
                $number["outputDesc"] = $output["desc"];
                $number["outputValue"] = $output["value"];
                $number["intervalIndicator"] = $output["intervalValue"];
                $number["upBound"] = $output["upBound"];
                $number["lowBound"] = $output["lowBound"];
                $number["numberAggregate"] = $output["aggregaMethod"];
                $number["workerId"] = $userId;
                $number["outputIndicator"] = OUTPUT_WITH_VALUE;
                array_push($numericaloutputs,$number);
                break;
            case ENUM_OUTPUT:
                $enumoutput = array();
                $enumoutput["actionId"] = $output["actionId"];
                $enumoutput["outputDesc"] = $output["desc"];
                $enumoutput["outputValue"] = $output["value"];
                $enumoutput["entries"] = $output["entries"];
                $enumoutput["enumAggregate"] = $output["aggregaMethod"];
                $enumoutput["workerId"] = $userId;
                $enumoutput["outputIndicator"] = OUTPUT_WITH_VALUE;
                array_push($enumoutputs,$enumoutput);
        }
    }

    //插入输出
    if($pictureoutput != null){
        $pictureoutputDAO = new PictureOutputDAO();
        $result = $pictureoutputDAO->insert($pictureoutput);
echo "The insert result is ".$result;echo "<br /><br />";
    }
    if(count($textoutputs) > 0){
        $textoutputDAO = new TextOutputDAO();
        foreach($textoutputs as $text){
            $result = $textoutputDAO->insert($text);
        }
    }
    if(count($numericaloutputs) > 0){
        $numberoutputDAO = new NumericalOutputDAO();
        foreach($numericaloutputs as $numericaloutput){
            $result = $numberoutputDAO->insert($numericaloutput);
        }
    }
    if(count($enumoutputs) > 0){
        $enumoutputDAO = new EnumOutputDAO();
        foreach($enumoutputs as $enumoutput){
            $result = $enumoutputDAO->insert($enumoutput);
        }
    }
    //返回结果
    return $result;
}

//更新相关信息：undertake，task
function updateRelatedInfo($userId,$stageId,$finishTime,$longitude,$latitude){
    //所需数据访问对象
    $undertakeDAO = new UndertakeDAO();
	$stageDAO = new StageDAO();
	$userDAO = new UserDAO();

    // 检查用户是否存在
    if ($userDAO->query($userId) == null)
        return -1;

    // 检查stage是否存在
    $stage = $stageDAO->query($stageId);
    if ($stage == null)
        return -1;

    //检查对应的undertake
    $tempUndertake = $undertakeDAO->queryByUserAndStage($userId,$stageId);
    if($tempUndertake == null)
        return -1;

    //更新stage的状态（是否多人情况不同）；更新task的状态（最后一个stage完成标志着task也完成）
    $updateResult = -1;

    //只有一个worker的情况
    if($stage->getWorkerNum() == 1){
        $updateResult = updateUndertakeInfo($tempUndertake,$finishTime);//更新该undertake本身的信息
        $updateResult = updateStageInfo($stage);//更新stage的状态为已完成，1的状态
        $updateResult = updateTaskInfo($stage,$userId,$longitude,$latitude,$finishTime);//更新task的信息
    }
    //有多个worker的情况
    else{
        $workerNum = $stage->getWorkerNum();
        $currentNum = count($undertakeDAO->queryByStage($stage->getId()));

        $undertakes = $undertakeDAO->queryByStage($stage->getId());
        //aggregateMethod：1是select the first finished, 2是select the most workers' answer， 3是user choose freely
        $aggregateMethod = $stage->getAggregateMethod();
        //选择第一个完成的
        if($aggregateMethod == 1){
            //记录之前是否已经有完成的
            $isFinished = false;
            foreach($undertakes as $undertake){
                if($undertake->getStatus() == Undertake::$STATUS_FINISHED){
                    $isFinished = true;
                    break;
                }
            }
            //之前没有已完成的，即是第一个完成
            if(!$isFinished){
                $updateResult = updateUndertakeInfo($tempUndertake,$finishTime);//更新该undertake本身的信息
                $updateResult = updateStageInfo($stage);//更新stage的状态为已完成，1的状态
                $updateResult = updateTaskInfo($stage,$userId,$longitude,$latitude,$finishTime);//更新task的信息
            }
            else{
                $updateResult = -2;//代表已经有人完成
            }
            //更新其它未完成的undertake状态为过期
            foreach($undertakes as $undertake){
                //&&后面很重要！！不能覆盖当前的undertake
                if($undertake->getStatus() == Undertake::$STATUS_ONGOING && $undertake->getId() != $tempUndertake->getId()){
                    $undertake->setStatus(Undertake::$STATUS_EXPIRED);
                    $undertakeDAO->update($undertake);
                }
            }
        }
        //如果不是第一个策略，那么都要等到接受的人数满了才行
        else {
            //如果还没有足够worker，那么仅仅更新该undertake信息即可
            if($currentNum < $workerNum)
                $updateResult = updateUndertakeInfo($tempUndertake,$finishTime);
            //如果已经有足够数量的worker，那么可能需要更新task的状态
            else{
                //如果存在未完成的undertake
                $isNotFinished = 0;
                foreach($undertakes as $undertake){
                    if($undertake->getStatus() != Undertake::$STATUS_FINISHED)
                        $isNotFinished++;
                }
                //除了当前worker还有其它worker没完成，只需更新当前undertake的状态
                if($isNotFinished > 1){
                    $updateResult = updateUndertakeInfo($tempUndertake,$finishTime);//更新该undertake本身的信息
                }
                //只有当前worker没完成，则还需要更新task的状态
                else{
                    $updateResult = updateUndertakeInfo($tempUndertake,$finishTime);//更新该undertake本身的信息
                    $updateResult = updateStageInfo($stage);//更新stage的状态为已完成，1的状态
                    $updateResult = updateTaskInfo($stage,$userId,$longitude,$latitude,$finishTime);//更新task的信息
                }

                //选大多数worker的答案
               if($aggregateMethod == 2){
                   //TODO: 聚合结果并存储到stage的aggregateResult当中
                }

            }
        }

    }

    return $updateResult;
}

//更新undertake本身的信息
function updateUndertakeInfo($tempUndertake,$finishTime){
    $undertakeDAO = new UndertakeDAO();
    $tempUndertake->setEndTime($finishTime);
    $tempUndertake->setStatus(Undertake::$STATUS_FINISHED);
    $result = $undertakeDAO->update($tempUndertake);
    return $result;
}

//更新stage的相关信息
function updateStageInfo($stage){
    $stageDAO = new StageDAO();
    $stage->setStatus(Stage::$STAGE_FINISHED);
    return $stageDAO->update($stage);
}

//更新task的相关信息
function updateTaskInfo($stage,$userId,$longitude,$latitude,$finishTime){
    $templateDAO = new TemplateDAO();
    $taskDAO = new TaskDAO();
    $stageDAO = new StageDAO();
    $undertakeDAO = new UndertakeDAO();
    $userDAO = new UserDAO();
    $locationDAO = new LocationDAO();
    //更新task的currentStage，或者更新task的状态为完成
    $task = $taskDAO->query($stage->getTaskId());
    $numOfStage = $templateDAO->query($task->getTemplateId())->getTotalStageNum();
    if($numOfStage == $stage->getIndex())
        $task->setStatus(Task::$STATUS_FINISHED);
    else {
        $task->setCurrentStage($stage->getIndex() + 1);

        //如果下一个stage的worker strategy是“same as the last stage's worker”，在用户点击完成任务后自动帮用户接下一这个任务的下一个阶段
        $nextStage = $stageDAO->queryStageByTaskAndIndex($task->getId(), $stage->getIndex() + 1);
        $workerStrategy = $nextStage->getRestrictions();
        //workerStragety：1是Same as the last stage's worker， 2是Different from all previous workers， 3是No requirement
        if($workerStrategy == 1){
            $autoUndertake = array();
            $autoUndertake["userId"] = $userId;
            $autoUndertake["stageId"] = $nextStage->getId();
            $autoUndertake["start_time"] = date('y-m-d h:i:s',time());
            $autoUndertake["end_time"] = null;
            $autoUndertake["status"] = Undertake::$STATUS_ONGOING;
            $template = $templateDAO->query($task->getTemplateId());
            $dest = $locationDAO->queryByStageAndType($nextStage->getId(), Location::$TYPE_DEST);
            /**
             * 设定
             */
            //如果不是最后一个stage，根据worker的当前位置动态计算contract
            if($template->getTotalStageNum() != $nextStage->getIndex()){
                $contract = $nextStage->getDeadline();
                if($dest != null){
                    $time = calTime($longitude, $latitude, $dest);
                    $time = $time + Constant::$TIME_EXTRA_FOR_WORKER * 60;//额外预留时间，默认为10分钟
                    $contractMillionSec = microtime() + $time * 1000;
                    $contract = date('Y-m-d H:i:s',$contractMillionSec);
                    //因为额外预留了十分钟，可能导致契约时间超过ddl，这里做一个比较和选择
                    if($contractMillionSec > strtotime($nextStage->getDeadline()))
                        $contract = $nextStage->getDeadline();
                }
                $autoUndertake["contract_time"] = $contract;
            }
            //否则直接设定为task的ddl
            else
                $autoUndertake["contract_time"] = $task->getDeadline();

            $autoResult = $undertakeDAO->insert($autoUndertake);
            //如果自动接任务成功，推送消息告知
            if($autoResult){
                $tool = new weixinTool("HPQwjnca_An3LjptuP8zdQWvxkOANDn3FhLygAHLwe0");
                $data = array();
                //中文转码
                $outDesc = mb_convert_encoding($nextStage->getDescription(),'UTF-8','GBK');
                $outAddress= mb_convert_encoding($dest->getAddress(),'UTF-8','GBK');
                //消息推送内容
                $data["title"] = "成功接受任务通知";
                $data["content"] = "因发布者任务设定，系统已自动帮您接受任务：".$outDesc."。当前目的地为：".$outAddress."。契约时间为：".$autoUndertake["contract_time"]."。请尽快出发完成任务。";
                //根据$userId查询相应的微信企业号账号，并推送消息
                $sql = "select * from user where userId = '{$userId}'";
                $conn = new db();
                $db = $conn->getDBConn();
                $row = $db->query($sql)->fetch(PDO::FETCH_ASSOC);//调用查询函数query(),并以关联数组的形式储存
                $weixinId = $row["weixinId"];
                $tool->send_message('textcard',1,$weixinId,$data);
            }
        }
    }

    //更新task本身的信息
    $updateResult = $taskDAO->update($task);
    if($updateResult > 0){
        if($numOfStage == $stage->getIndex()){
            $user = $userDAO->query($userId);
            //推送消息，告知任务已完成
            $tool = new weixinTool("HPQwjnca_An3LjptuP8zdQWvxkOANDn3FhLygAHLwe0");
            $data = array();
            //中文转码
			$outTitle = mb_convert_encoding($task->getTitle(),'UTF-8','GBK');
			$outAccount = mb_convert_encoding($user->getAccount(),'UTF-8','GBK');
			//消息推送内容
			$title = "任务完成通知";
			$content = "您发布的任务：".$outTitle."已由".$outAccount."于".$finishTime."完成。您可以打开APP查看详细信息。";
            $data["title"] = $title;
            $data["content"] = $content;
			//根据$userId查询相应的微信企业号账号，并推送消息
            $sql = "select * from user where userId = '{$task->getUserId()}'";
            $conn = new db();
      		$db = $conn->getDBConn();
            $row = $db->query($sql)->fetch(PDO::FETCH_ASSOC);//调用查询函数query(),并以关联数组的形式储存
            $weixinId = $row["weixinId"];
            $tool->send_message('textcard',1,$weixinId,$data);
        }
    }
    return $updateResult;
}

//计算时间预估
function calTime($longitude,$latitude,$currentDest){
    $result = json_decode(HttpUtil::doGet($latitude,$longitude,$currentDest->getLatitude(),$currentDest->getLongitude()),true);
    if($result["status"] == 0){
        $result = $result["result"][0];
        $time = $result["duration"]["value"];
        return $time;
    }
    return -1;
}
?>
